package br.com.it4.zmed.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import br.com.it4.framework.persistence.exception.PersistenceException;
import br.com.it4.framework.util.exception.BusinessException;
import br.com.it4.framework.util.exception.SystemException;
import br.com.it4.zmed.entity.Medico;
import br.com.it4.zmed.filter.MedicoFilter;
import br.com.it4.zmed.persistence.MedicoDAO;

/**
 * Classe de acesso as funcionalidades de medico.
 * 
 * @author Mozart Silva (mozart.vsilva@gmail.com)
 * 
 */
@Service(value = "medicoService")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class MedicoServiceImpl implements MedicoService {

    /** Interface de acesso ao repositório do medico. */
    @Autowired
    private MedicoDAO medicoDAO;

    /** {@inheritDoc} */
    public Medico addMedico(Medico medico) throws SystemException, BusinessException {
        this.validateAddOrUpdate(medico);

        Medico medicoBusca = new Medico();
        medicoBusca.setCrm(medico.getCrm());

        // Verifica se já existe um medico cadastro com o mesmo código.
        if (this.getMedico(medico.getCrm()) != null) {
            // throw new
            // BusinessException(BusinessCode.SISTEMA_CODIGO_EXISTENTE);
        }

        try {
            return this.medicoDAO.add(medico);
        } catch (PersistenceException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /** {@inheritDoc} */
    public Medico updateMedico(Medico medico) throws SystemException, BusinessException {
        this.validateAddOrUpdate(medico);
        try {
            return this.medicoDAO.update(medico);
        } catch (PersistenceException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /** {@inheritDoc} */
    public void removeMedico(Medico medico) throws SystemException {
        try {
            this.medicoDAO.remove(medico);
        } catch (PersistenceException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /** {@inheritDoc} */
    public Medico getMedico(String crm) throws SystemException {
        Medico medico = null;
        
        try {
            medico = this.medicoDAO.get(crm);
        } catch (PersistenceException e) {
            throw new SystemException(e);
        }

        return medico;
    }

    /** {@inheritDoc} */
    public List<Medico> getMedicos(MedicoFilter filtro) throws SystemException {
        List<Medico> medicos = null;

        try {
            medicos = this.medicoDAO.get(filtro);
        } catch (PersistenceException e) {
            throw new SystemException(e);
        }

        return medicos;
    }

    /** {@inheritDoc} */
    public List<Medico> getMedicos(MedicoFilter filtro, int registroInicio, int registroFim)
            throws SystemException {
        List<Medico> medicos = null;

        try {
            medicos = this.medicoDAO.get(filtro, registroInicio, registroFim);
        } catch (PersistenceException e) {
            throw new SystemException(e);
        }

        return medicos;
    }

    /** {@inheritDoc} */
    public Long getMedicosCount(MedicoFilter filtro) throws SystemException {
        Long count = null;

        try {
            count = this.medicoDAO.getCount(filtro);
        } catch (PersistenceException e) {
            throw new SystemException(e);
        }

        return count;
    }

    /**
     * Valida o medico a ser salvo.
     * 
     * @param medico
     *            O medico a ser validado.
     * @throws BusinessException
     *             Exceção caso ocorra erro na validação.
     */
    private void validateAddOrUpdate(Medico medico) throws BusinessException {
        List<String> messages = new ArrayList<String>();

        // if (medico.getCodigo() == null ||
        // medico.getCodigo().trim().isEmpty()) {
        // messages.add(BusinessCode.SISTEMA_CODIGO_OBRIGATORIO);
        // }
        //
        // if (medico.getCodigo() != null &&
        // medico.getCodigo().length() > 10) {
        // messages.add(BusinessCode.SISTEMA_CODIGO_TAMANHO_INVALIDO);
        // }
        //
        // if (medico.getNome() == null ||
        // medico.getNome().trim().isEmpty()) {
        // messages.add(BusinessCode.SISTEMA_NOME_OBRIGATORIO);
        // }
        //
        // if (medico.getNome() != null && medico.getNome().length() >
        // 100) {
        // messages.add(BusinessCode.SISTEMA_NOME_TAMANHO_INVALIDO);
        // }

        if (!messages.isEmpty()) {
            throw new BusinessException(messages);
        }
    }

}